#include <iostream>
#include <boost/foreach.hpp>
#include "mapped_file.h++"
#include "word_tree.h++"
#include "serializer.h++"

int main(int argc, char **argv) {
	int error_count = 0;
	const char* wordz[] = {
		"fucked", "fuckedup", "foque", "facorsay", "factory", "forum",
		"feux", "fb", "fdma", "fzgz", "ftdma", "fpdma", "ficelle",
		"fm", "flock", "fhu", "fground"
	};
	const char* nonpresent_wordz[] = {
		"fack", "fock", "abcd", "foreground", "factories", "forii",
		"feuxdelamour", "fessebouc", "floatingpoint"
	};
	if (argc < 3) {
		std::cout << "MOAR ARG" << std::endl;
		return 1;
	}
	std::string file(argv[1]);
	std::string file2(argv[2]);

	UnserializedDocument fake_doc1("fake/doc1");
	UnserializedDocument fake_doc2("fake/doc2");

	float fake_tfidf = 0.f;
	size_t i;
	{
		WordTree::UnserializedNode root(0);
		BOOST_FOREACH(const char* e, wordz) {
			WordTree::UnserializedNode& un =
					root.create_get_word(e);
			un.addDocumentMatch(&fake_doc1, i++);
			un.setDocumentMatchTfIdf(&fake_doc1, fake_tfidf+=1.0f);
			un.addDocumentMatch(&fake_doc2, i++);
			un.setDocumentMatchTfIdf(&fake_doc2, fake_tfidf+=1.0f);
		}
		root.print_representation(std::cout);
		WritableMappedMemory f(file);
		WritableMappedMemory f2(file2);

		Serializer serializer;
		serializer.set_wordtree_file(&f);
		serializer.set_moreinfo_file(&f2);
		serializer.set_documents_file(&f2);
		serializer.set_paths_file(&f2);
		serializer.set_postings_file(&f2);

		serializer.serialize_document(fake_doc1);
		serializer.serialize_document(fake_doc2);
		serializer.serialize_node_header(root);
		//root.serialize_tree(f);

		// f is closed on the following curly brace.
	}
	{
		ReadOnlyMappedMemory nodefile(file);
		ReadOnlyMappedMemory elsefile(file2);
		WordTree::NodeHeader& root = nodefile.get_header(
				).get_object_after<WordTree::NodeHeader>();
		BOOST_FOREACH(const char* e, nonpresent_wordz)
			if (root.getWord(nodefile, e)) {
				std::cerr << "non present word " << e
					<< " exists ?!?" << std::endl;
				error_count++;
			}
		float faked_tfidf = 1.f;
		BOOST_FOREACH(const char* e, wordz) {
			WordTree::NodeHeader* node = root.getWord(nodefile, e);
			if (!node) {
				std::cerr << "present word " << e
					<< " doesn't exists ?!?" << std::endl;
				error_count++;
				continue;
			}
			DetailedDataHeader& detailed = 
					elsefile.get(node->get_detailed_data());
			if (detailed.nb_docs != 2) {
				std::cerr << "present word is present in "
					<< detailed.nb_docs
					<< " instead of 2 ?!?" << std::endl;
				error_count++;
				continue;
			}
			DetailedDataHeader::document_table_type doctable(
					detailed.getDocumentTable());
			DetailedDataHeader::tfidf_table_type tfitable(
					detailed.getTFIDFTable());
			size_t i;
			for (i = 0; i < 2; ++i) {
				PointerTo<Document>* d(doctable.getElement(i));
				MemoryMappedFloat* val(tfitable.getElement(i));
				Document& doc = elsefile.get(*d);
				std::string path(doc.get_path_string(elsefile));
				float expected = faked_tfidf;
				if (path == "fake/doc2") {
					expected += 1.0f;
				} else if (path != "fake/doc1") {
					std::cerr << "unknown document "
						<< path << std::endl;
					error_count++;
					continue;
				}
				if (val->value != expected) {
					std::cerr << "wrong faked tfidf "
						": expected " << faked_tfidf
						<< " got " << val->value
						<< std::endl;
					error_count++;
				}
			}
			faked_tfidf += 1.0f;
			faked_tfidf += 1.0f;
		}
	}
	return error_count;
}

